<?php
// WARNING: this will work only in PHP5
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
require_once(DOKU_INC.'phpincludes/mail_html.php');


/**
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Stephane Chamberland <dokuwiki@meteokid.ca>
 * @date       2009-01-27
 */
class ACC_Form_Base {

    var $localized = false;
    var $lang   = array();
    var $parent = NULL;
    var $buro   = NULL;
    var $reset = NULL;

    var $formDescFtmName = 'formDescFmt';

    var $mailTo = '';  //to be overridden by derived class
    var $mailToAllowed = array(); //should be overridden by derived class; set to true for allowed all (danger of spam)
    var $mailToField = 'email_to';
    var $mailFromField = 'email_from';
    var $mailFromNameField = 'from_name';
    var $mailSubjectPrefix = '[ACC Form] '; //to be overridden by derived class
    var $mailSubjectFmtName = 'mailSubjectFmt';
    var $mailBodyFmtName = 'mailBodyFmt';

    var $metaFileSuffix = 'acc'; //to be overridden by derived class

    var $langArray = array();  //to be overridden by derived class

    function _getFormDescFieldsVals($formDescFmtName) {
        return array(); //TODO: needs to be implement by the derived class
    }

    function _postcheckpost($data) {
        return array(); //TODO: needs to be implement by the derived class
    }

    function _preActionValuesMods($values) {
        return $values;
    }

    function _action_ok($data,$thanks) {
        return $thanks; //TODO: needs to be implement by the derived class
    }

    function _action_errors($data,$errors) {
        return false; //TODO: needs to be implement by the derived class
    }

    //--------------------------------------------------------------

    public function __construct($parent) {
        global $conf;

        $this->parent = $parent;

        if(!$this->mailTo && isset($conf['notify'])) $this->mailTo = $conf['notify'];

        if(!plugin_isdisabled('bureaucracy')) {
            $this->buro =& plugin_load('helper', 'bureaucracy');
        }

   }

    function getLang($id) {
        global $conf;
        if (!$this->localized) {
            $this->localized = true;
            $this->lang = isset($this->langArray['en']) ? $this->langArray['en'] : array();
            if(isset($this->langArray[$conf['lang']])) $this->lang = array_merge($this->lang,$this->langArray[$conf['lang']]);
        }
        return (isset($this->lang[$id]) ? $this->lang[$id] : $v);
    }

    //--------------------------------------------------------------

    function _getFormDescData($formDescFmtName=false) {
        global $conf;
        if(!$formDescFmtName) $formDescFmtName = $this->formDescFmtName;
        $descFmt = $this->getLang($formDescFmtName);
        $descFmtVals = $this->_getFormDescFieldsVals($formDescFmtName);
        $desc = str_replace(array_keys($descFmtVals),array_values($descFmtVals),$descFmt);
        return $this->buro->_parse_form_def($desc);
    }

    function _buildSearchReplaceArray($values0) {
        $values = $this->_preActionValuesMods($values0);
        if (!is_array($values)) $values = $values0;

        $replace = array();
        foreach($values as $k=>$v) {
            $replace['__'.$k.'__'] = $v;
        }
        $values_list = '';
        foreach($values as $k=>$v) $values_list .= $k." = ".$v."\n";
        $replace['__ACC_Form_list_all__'] = $values_list;
        return $replace;
    }

    function _str_replace_from_values($str,$values) {
        $replace = $this->_buildSearchReplaceArray($values);
        return str_replace(array_keys($replace),array_values($replace),$str);
    }

    //--------------------------------------------------------------

    function _action_show_form($formDescFmtName='formDescFmt') {
        global $conf;
        $formData = $this->_getFormDescData($formDescFmtName);
        echo '<a name="'.$formData['name'].'"></a>';
        $reset = true;
        $error = array();
        if(isset($_POST[$formData['name']])){
            $reset = false;
            $errors = $this->buro->_checkpost($formData['data']);
            if (!count($errors)) {
                $errors = $this->_postcheckpost($formData['data']);
            }
            if (!count($errors)) {
                $ok = $this->_action_ok($formData['data'],$formData['thanks']);
                if ($ok) {
                    echo '<div class="success" id="scroll__here"><p>';
                    echo $ok;
                    echo '</p></div>';
                    //msg($formData['thanks'],1);
                    $reset = true;
                } else {
                    $ok = $this->_action_errors($formData['data'],$errors);
                }
            }
            $formData = $this->_getFormDescData($formDescFmtName);
        }
        if(!is_null($this->reset)) $reset = $this->reset;
        print($this->buro->_htmlform($formData['data'],$errors,$reset));
    }

    //--------------------------------------------------------------

    protected function _sendMail($values0) {
        global $conf,$ID;
        require_once(DOKU_INC.'inc/mail.php');

        //Collect posted data
        //$values = $this->buro->_collectpost($postValues;);
        $values = $this->_preActionValuesMods($values0);
        if (!is_array($values)) $values = $values0;

        $to = $this->mailTo;
        if (isset($values[$this->mailToField])) {
            if ($this->mailToAllowed === true || (is_array($this->mailToAllowed) && in_array($values[$this->mailToField],$this->mailToAllowed))) {
                $to = $values[$this->mailToField];
            } else {
                msg('Not allowed to send msg to: '.hsc($values[$this->mailToField])); //TODO: localize
                return '';
            }
        }
        $fromName = isset($values[$this->mailFromNameField]) ? $values[$this->mailFromNameField] : '';
        $fromEmail = isset($values[$this->mailFromField]) ? $values[$this->mailFromField] : $conf['mailfrom'];
        $from = $fromName.' <'.$fromEmail.'>';

        $searchReplace = $this->_buildSearchReplaceArray($values) ;
        $search = array_keys($searchReplace);
        $replace = array_values($searchReplace);
        $subject = str_replace($search,$replace,$this->getLang($this->mailSubjectFmtName));
        $body = str_replace($search,$replace,$this->getLang($this->mailBodyFmtName));

/*
        echo '<pre>_sendMail'."\n";
        echo 'to     :'.hsc($to)."\n";
        echo 'from   :'.hsc($from)."\n";
        echo 'subject:'.hsc($this->mailSubjectPrefix.$subject)."\n";
        echo 'body:'.hsc($body)."\n";
        echo '</pre>'."\n";
*/

        $ok = mail_send($to, $this->mailSubjectPrefix.$subject, $body, $from);
        return $ok;
    }

    //--------------------------------------------------------------

    function _metaFileName($id=false) {
        global $ID;
        if (!$id) $id = $ID;
        return metaFN($id, '.'.$this->metaFileSuffix);
    }

    function _metaFile_get($id=false) {
        $file = $this->_metaFileName($id);
        if (@file_exists($file)) {
            $fields = unserialize(io_readFile($file, false));
        } else {
            $fields = array();
        }
        return $fields;
    }

    function _metaFile_save($fields,$id=false) {
        $file = $this->_metaFileName($id);
/*
        echo '<pre>_metaFile_save: '.$file."\n";
        print_r($fields);
        echo '</pre>'."\n";
*/
        return io_saveFile($file, serialize($fields));
    }

    function _metaFile_add($fields,$values0,$uid=NULL,$status=NULL) {
        $values = $this->_preActionValuesMods($values0);
        if (!is_array($values)) $values = $values0;
        if (is_null($uid)) {
            $uid = uniqid();
            if (isset($values['uid'])) $uid = $values['uid'];
        }
        if (is_null($status)) {
            $status = 'new';
            if (isset($values['status'])) $status = $values['status'];
        }
        $values['status'] = $status;
        //TODO: may want to check if in allowed fields
        $fields[$uid] = $values;
        return $fields;
    }

    function _metaFile_update($fields,$uid,$status=NULL,$values=NULL) {
        if (is_null($status) && is_null($values)) return $fields;
        if (!isset($fields[$uid])) return $fields;
        if (is_null($status)) {
            $status = $fields[$uid]['status'];
        } else {
            $fields[$uid]['status'] = $status;
        }
        if (!is_null($values)) return $this->_metaFile_add($fields,$values,$uid,$status);
    }

    function _metaFile_search($fields,$values,$uid0=NULL) {
        if (!is_null($uid0)) {
            if (!isset($fields[$uid0])) return array();
            $searchlist = array($uid0);
        } else {
            $searchlist = array_keys($fields);
        }
        $matchlist = array();
        foreach($searchlist as $uid) {
            $ok = true;
            foreach($values as $k=>$v) {
                if (!isset($fields[$uid][$k]) || $fields[$uid][$k] != $v) {
                    $ok = false;
                }
            }
            if ($ok) $matchlist[] = $uid;
        }
        return $matchlist;
    }
    
    /**
     *
     */
    function _stripHTMLtags($txt,$utf8=false){
        //$txt = preg_replace('/<style[^<>]*>.*<\/style>/i','',$txt); //TODO: non greedy pattern matching
        //$txt = preg_replace('/<script[^<>]*>.*<\/script>/i','',$txt); //TODO: non greedy pattern matching
        $txt = str_replace(array('<br />','<br>','<br/>','&#039;'),array("\n","\n","\n","'"), $txt);
        $txt = preg_replace('/<[^<>]+>/','',$txt);
        if($utf8) return html_entity_decode(utf8_decode($txt));
        else return html_entity_decode($txt);
    }


}